import uvicorn
from fastapi import FastAPI
from fastapi.exceptions import RequestValidationError
from starlette.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse, HTMLResponse
from starlette.staticfiles import StaticFiles

import settings
#from errors import JPGError, FileMaxSizeError
from app import user_router

app = FastAPI()

app.mount("/static", StaticFiles(directory=settings.STATIC_DIR), name="static")

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)


# 自定义异常处理
@app.exception_handler(Exception)
async def handler_custom_error(request: Request, exc):
    if isinstance(exc, JPGError):
        return JSONResponse({"message": "图片格式类型错误！"}, 421)
    if isinstance(exc, FileMaxSizeError):
        return JSONResponse({"message": "图片大小不能超过2M"}, 401)


# 自定义处理请求数据验证错误
@app.exception_handler(RequestValidationError)
async def handler_validation_error(req, e: RequestValidationError):
    # print([a for a in dir(e) if not a.startswith("__")])
    errors = {
        'value_error.missing': '必填项',
        'type_error.integer': '字段内容必须是数值',
        'value_error.str.regex': '字段的数据类型不合法: {}',
        'value_error.any_str.min_length': '不满足最小字符串长度: {}',
        'value_error.any_str.max_length': '超过最大字符串长度: {}'
    }
    # print(e.body)
    # print(e.errors())
    resp_error = {
        item['loc'][-1]: errors[item['type']].format(list(item['ctx'].values())[0]) if 'ctx' in item else errors[
            item['type']]
        for item in e.errors()
    }
    return JSONResponse({'errors': resp_error}, status_code=400)


@app.exception_handler(404)
async def handler_not_found(request: Request, error):
    html = f"""
        <h1 style="color: red">404 Not Found</h1>
        <h3>当前请求地址：{request.url}</h3>
    """
    return HTMLResponse(html, status_code=404)


app.include_router(user_router, prefix='/user')

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
